package com.softhinker.ke24.unit3.engine;

import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

import javax.swing.BoxLayout;
import javax.swing.ButtonGroup;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JTextField;

import com.softhinker.ke24.unit3.listener.QuestionListener;
import com.softhinker.ke24.unit3.listener.UserProfileListener;
import com.softhinker.ke24.unit3.model.Affordability;
import com.softhinker.ke24.unit3.model.GreedLevel;
import com.softhinker.ke24.unit3.model.ProfessionLevel;
import com.softhinker.ke24.unit3.model.UserProfile;

public class QuestionProvider implements ActionListener {

	private QuestionListener renderer;
	private List<String> questions = new ArrayList<String>();
	private List<JComponent> options = new ArrayList<JComponent>();
	private List<UserProfileListener> resultListeners = new ArrayList<UserProfileListener>();
	private JPanel optionPanel;
	
	private int indexOfPreviousQuestion = 0;
	private int indexOfCurrentQuestion = 0;
	
	private GreedLevel greedLevel;
	private Affordability affordability;
	private ProfessionLevel professionLevel;
	
	public QuestionProvider(){
		init();
		loadQuestions();
		loadOptions();
	}
	
	public void addResultListener(UserProfileListener listener){
		if(listener != null){
			this.resultListeners.add(listener);
		}
	}
	
	public void setQuestionListener(QuestionListener renderer){
		this.renderer = renderer;
	}
	
	private void init(){
		greedLevel = new GreedLevel();
		affordability = new Affordability();
		professionLevel = new ProfessionLevel();
		optionPanel = new JPanel();
		indexOfPreviousQuestion = 0;
		indexOfCurrentQuestion = 0;
	}
	
	@Override
	public void actionPerformed(ActionEvent e) {
		renderer.displayError(null);
		String command = e.getActionCommand();
		
		if("Submit".equals(command)){
			for(UserProfileListener listener : this.resultListeners){
				listener.publishUserProfile(new UserProfile(greedLevel, affordability, professionLevel));
			}
			return;
		}
		
		if("Restart".equals(command)){
			init();
			renderer.restart();
			return;
		}
		
		int temp = 0;
		try{
			int i = Integer.parseInt(command);
			int size = this.questions.size();
			if(i < 0 || i >= size){
				renderer.displayError("Command is out of range : " + i);
			} else {
				//Keep record of where the position is.
				temp = indexOfPreviousQuestion;//For reverting purpose in case exception occurs during processing
				indexOfPreviousQuestion = indexOfCurrentQuestion;
				indexOfCurrentQuestion = i;
				
				//Save answer
				saveAnswer(this.optionPanel.getComponent(0));
				
				//Change question and option
				renderer.renderQuestion(this.questions.get(i));
				this.optionPanel.remove(0);
				this.optionPanel.repaint();
				this.optionPanel.add(this.options.get(i), 0);
				if(i == (size - 1)){
					renderer.updateActionCommand(String.valueOf(i - 1), null);
//					inspectThisUser();
					
				} else if(i == 0){
					renderer.updateActionCommand(null, String.valueOf(i + 1));
				} else{
					renderer.updateActionCommand(String.valueOf(i - 1), String.valueOf(i + 1));
				}
				
			}
			
		} catch(Exception ex){
			renderer.displayError("Invalid command[" + command + "] : " + ex.getLocalizedMessage());
			//Revert
			this.indexOfCurrentQuestion = this.indexOfPreviousQuestion;
			this.indexOfPreviousQuestion = temp;
		}
		
	}

	public String getFirstQuestion(){
		return questions.get(0);
	}
	
	public JComponent getFirstOption(){
		this.optionPanel.add(this.options.get(0),0);
		return this.optionPanel;
	}
	
	private void loadQuestions(){
		InputStream is = this.getClass().getResourceAsStream("Questions.txt");
		Scanner scanner = new Scanner(is);
		while(scanner.hasNextLine()){
			questions.add(scanner.nextLine());
		}
	}
	
	private void loadOptions(){
		// option for question 1
		JTextField field1 = new JTextField(5);
		field1.setText(String.valueOf(this.greedLevel.getExpectedROI() * 100));
		JLabel label1 = new JLabel("%");
		label1.setLabelFor(field1);
		JPanel panel1 = new JPanel();
		panel1.add(field1,0);
		panel1.add(label1,1);
		this.options.add(panel1);
		
		//option for question 2
		JTextField field2 = new JTextField(5);
		field2.setText(String.valueOf(this.greedLevel.getInvestmentTimeSpan()));
		JLabel label2 = new JLabel("day(s)");
		label2.setLabelFor(field2);
		JPanel panel2 = new JPanel();
		panel2.add(field2,0);
		panel2.add(label2,1);
		this.options.add(panel2);
		
		//option for question 3
		JPanel panel3 = new JPanel();
		panel3.setLayout(new BoxLayout(panel3, BoxLayout.PAGE_AXIS));
		ButtonGroup group3 = new ButtonGroup();
		JRadioButton radio3_1 = new JRadioButton("Selling price = Expected ROI");
		radio3_1.setActionCommand("1");
		if(this.greedLevel.getAcceptedSellingPoint() == 1){
			radio3_1.setSelected(true);
		} else{
			radio3_1.setSelected(false);
		}
		group3.add(radio3_1);
		JRadioButton radio3_2 = new JRadioButton("Buying price < Selling point < Expected ROI");
		radio3_2.setActionCommand("0");
		if(this.greedLevel.getAcceptedSellingPoint() == 0){
			radio3_2.setSelected(true);
		} else{
			radio3_2.setSelected(false);
		}
		group3.add(radio3_2);
		JRadioButton radio3_3 = new JRadioButton("Selling point < Buying price");
		radio3_3.setActionCommand("-1");
		if(this.greedLevel.getAcceptedSellingPoint() == -1){
			radio3_3.setSelected(true);
		} else{
			radio3_3.setSelected(false);
		}
		group3.add(radio3_3);
		panel3.add(radio3_1, 0);
		panel3.add(radio3_2, 1);
		panel3.add(radio3_3, 2);
		this.options.add(panel3);
		
		//option for question 4
		JTextField field4 = new JTextField(5);
		field4.setText(String.valueOf(this.affordability.getAffordableMaximumLost() * 100));
		JLabel label4 = new JLabel("%");
		label4.setLabelFor(field4);
		JPanel panel4 = new JPanel();
		panel4.add(field4, 0);
		panel4.add(label4, 1);
		this.options.add(panel4);
		
		//option for question 5
		JPanel panel5 = new JPanel();
		panel5.setLayout(new BoxLayout(panel5, BoxLayout.PAGE_AXIS));
		ButtonGroup group5 = new ButtonGroup();
		JRadioButton radio5_1 = new JRadioButton("Yes");
		radio5_1.setActionCommand("1");
		if(this.affordability.getContinueToInvest() == 1){
			radio5_1.setSelected(true);
		} else{
			radio5_1.setSelected(false);
		}
		group5.add(radio5_1);
		JRadioButton radio5_2 = new JRadioButton("Maybe");
		radio5_2.setActionCommand("0");
		if(this.affordability.getContinueToInvest() == 0){
			radio5_2.setSelected(true);
		} else{
			radio5_2.setSelected(false);
		}
		group5.add(radio5_2);
		JRadioButton radio5_3 = new JRadioButton("No");
		radio5_3.setActionCommand("-1");
		if(this.affordability.getContinueToInvest() == -1){
			radio5_3.setSelected(true);
		} else{
			radio5_3.setSelected(false);
		}
		group5.add(radio5_3);
		panel5.add(radio5_1, 0);
		panel5.add(radio5_2, 1);
		panel5.add(radio5_3, 2);
		this.options.add(panel5);
		
		//option for question 6
		JTextField field6 = new JTextField(5);
		field6.setText(String.valueOf(this.professionLevel.getYearsOfInvestment()));
		JLabel label6 = new JLabel("year(s)");
		label6.setLabelFor(field6);
		JPanel panel6 = new JPanel();
		panel6.add(field6, 0);
		panel6.add(label6, 1);
		this.options.add(panel6);
		
		//option for question 7
		JPanel panel7 = new JPanel();
		panel7.setLayout(new BoxLayout(panel7, BoxLayout.PAGE_AXIS));
		ButtonGroup group7 = new ButtonGroup();
		JRadioButton radio7_1 = new JRadioButton("Yes");
		radio7_1.setActionCommand("true");
		group7.add(radio7_1);
		JRadioButton radio7_2 = new JRadioButton("No");
		radio7_2.setActionCommand("false");
		group7.add(radio7_2);
		if(this.professionLevel.isInFinanceIndustry()){
			radio7_1.setSelected(true);
			radio7_2.setSelected(false);
		} else{
			radio7_1.setSelected(false);
			radio7_2.setSelected(true);
		}
		panel7.add(radio7_1, 0);
		panel7.add(radio7_2, 1);
		this.options.add(panel7);
	}
	
	private void saveAnswer(Component component) throws Exception{
		JPanel panel = (JPanel)component;
		switch(this.indexOfPreviousQuestion){
			case 0 : {
				JTextField roi = (JTextField)panel.getComponent(0);
				this.greedLevel.setExpectedROI(Double.parseDouble(roi.getText()) / 100);
				break;
			}
			case 1 : {
				JTextField days = (JTextField)panel.getComponent(0);
				this.greedLevel.setInvestmentTimeSpan(Integer.parseInt(days.getText()));
				break;
			}
			case 2 : {
				if(((JRadioButton)panel.getComponent(0)).isSelected()){
					this.greedLevel.setAcceptedSellingPoint(Integer.parseInt(((JRadioButton)panel.getComponent(0)).getActionCommand()));
				} else if(((JRadioButton)panel.getComponent(1)).isSelected()){
					this.greedLevel.setAcceptedSellingPoint(Integer.parseInt(((JRadioButton)panel.getComponent(1)).getActionCommand()));
				} else if(((JRadioButton)panel.getComponent(2)).isSelected()){
					this.greedLevel.setAcceptedSellingPoint(Integer.parseInt(((JRadioButton)panel.getComponent(2)).getActionCommand()));
				} else{
					throw new IllegalArgumentException("Please choose one option to continue!");
				}
				break;
			}
			case 3 : {
				JTextField lost = (JTextField)panel.getComponent(0);
				this.affordability.setAffordableMaximumLost(Double.parseDouble(lost.getText()) / 100);
				break;
			}
			case 4 : {
				if(((JRadioButton)panel.getComponent(0)).isSelected()){
					this.affordability.setContinueToInvest(Integer.parseInt(((JRadioButton)panel.getComponent(0)).getActionCommand()));
				} else if(((JRadioButton)panel.getComponent(1)).isSelected()){
					this.affordability.setContinueToInvest(Integer.parseInt(((JRadioButton)panel.getComponent(1)).getActionCommand()));
				} else if(((JRadioButton)panel.getComponent(2)).isSelected()){
					this.affordability.setContinueToInvest(Integer.parseInt(((JRadioButton)panel.getComponent(2)).getActionCommand()));
				} else{
					throw new IllegalArgumentException("Please choose one option to continue!");
				}
				break;
			}
			case 5 : {
				JTextField years = (JTextField)panel.getComponent(0);
				this.professionLevel.setYearsOfInvestment(Integer.parseInt(years.getText()));
				break;
			}
			case 6 : {
				if(((JRadioButton)panel.getComponent(0)).isSelected()){
					this.professionLevel.setInFinanceIndustry(true);
				} else if(((JRadioButton)panel.getComponent(1)).isSelected()){
					this.professionLevel.setInFinanceIndustry(false);
				} else{
					throw new IllegalArgumentException("Please choose one option to continue!");
				}
				break;
			}
		}
	}
	
//	private void inspectThisUser(){
//		System.out.println("********* Greed Level *********");
//		System.out.println(this.greedLevel);
//		System.out.println("********* Affordability *********");
//		System.out.println(this.affordability);
//		System.out.println("********* Profession Level *********");
//		System.out.println(this.professionLevel);
//	}
}
